
package com.lgcns.android2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.TabActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;

public class MainActivity extends TabActivity implements OnClickListener{

    private final static int DIALOG_UPDATE = 1;
    private final static int DIALOG_NOT_UPDATE = 2;
    private final static int DIALOG_PROGRESS = 3;
    private final static int DIALOG_PROGRESS_DONE = 4;
    private final static int DIALOG_ERROR_DB_INFO = 5;
    private final static int DIALOG_ERROR_DB_DOWNLOAD = 6;
    
    public static String TAG = "Android2Team";
    
    private TabHost mTabHost;
    private Animation translateLeftAnim;
    //private Animation translateRightAnim;
    
    private ProgressDialog mProgressDialog;
    private DBInfoItem mDbInfo;
    
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        setContentView(R.layout.main);

        mTabHost = getTabHost();
        mTabHost.getTabWidget().setDividerDrawable(R.drawable.tab_divider);

        setupTab(new Intent(this, TeamActivity.class), "Team");
        setupTab(new Intent(this, PhotoActivity.class), "Photo");
        setupTab(new Intent(this, ProfileListActivity.class), "Members");

        // TO DO : Preference 에서 선택 할 수 있도록...
        mTabHost.setCurrentTab(0);

        translateLeftAnim = AnimationUtils.loadAnimation(this, R.anim.push_left_in);
        //translateRightAnim = AnimationUtils.loadAnimation(this, R.anim.push_left_out);
        
        mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
            @Override
            public void onTabChanged(String tabId) {
                mTabHost.getCurrentView().startAnimation(translateLeftAnim);
            }
        });
        
        findViewById(R.id.title_button).setOnClickListener(this);

    }
    
    private void setupTab(final Intent intent, final String tag) {
        View tabView = LayoutInflater.from(this).inflate(R.layout.tab_background, null);
        TextView tv = (TextView) tabView.findViewById(R.id.tabsText);
        tv.setText(tag);
        
        TabSpec setContent = mTabHost.newTabSpec(tag).setIndicator(tabView).setContent(intent);
        mTabHost.addTab(setContent);
    }

	@Override
	public void onClick(View view) {
		switch(view.getId()) {
		case R.id.title_button :
		    DBInfoJob job = new DBInfoJob();
		    job.execute();

			break;
		}
	}

	@Override
	public Dialog onCreateDialog(int id) {
		if (id == DIALOG_UPDATE) {
			return new AlertDialog.Builder(this)
			.setIcon(android.R.drawable.ic_dialog_alert)
			.setTitle("Inform")
			.setMessage("업데이트할 내용이 존재합니다.\n\n업데이트 하시겠습니까?")
		    .setPositiveButton(android.R.string.ok,	new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog,	int which) {
				    showDialog(DIALOG_PROGRESS);
				}
			})
			.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dismissDialog(DIALOG_UPDATE);
                }
			}).create();
		} else if (id == DIALOG_NOT_UPDATE) {
			return new AlertDialog.Builder(this)
			.setIcon(android.R.drawable.ic_dialog_alert)
			.setTitle("Inform")
			.setMessage("업데이트 할 내용이 없습니다.")
			.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dismissDialog(DIALOG_NOT_UPDATE);
                }
            }).create();
		} else if (id == DIALOG_PROGRESS) {
		    DBDownloadJob job = new DBDownloadJob();
		    job.execute();
		    
            return mProgressDialog;
		} else if (id == DIALOG_PROGRESS_DONE) {
		    return new AlertDialog.Builder(this)
            .setIcon(android.R.drawable.ic_dialog_info)
            .setTitle("Inform")
            .setMessage("업데이트가 완료되었습니다.\n\n어플리케이션을 재시작 합니다.")
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // Application restart
                    Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); 
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
                    startActivity(i);
                    
                    finish();
                }
            })
            .create();
        } else if (id == DIALOG_ERROR_DB_INFO) {
            // DB info 다운로드 에러  창
            return new AlertDialog.Builder(this)
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setTitle("Error")
            .setMessage("최신 DB 정보를 가져올 수 없습니다.")
            .setPositiveButton(android.R.string.ok, null)
            .create();
        } else if (id == DIALOG_ERROR_DB_DOWNLOAD) {
            // DB 파일 다운로드 에러  창
            return new AlertDialog.Builder(this)
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setTitle("Error")
            .setMessage("DB 다운로드 중 오류가 발생하였습니다.")
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                    return;
                }
            })
            .create();
        }
		return null;
	}
	
    private boolean hasUpdated(String serverDbVersion) {
        SharedPreferences prefs = getSharedPreferences(Constants.DB_VERSION_KEY, MODE_PRIVATE);
        String currentDbVersion = prefs.getString(Constants.DB_VERSION_KEY, "");

        Log.d(TAG, "Current Db Version : " + currentDbVersion + ", Server Db Version : " + serverDbVersion);
        
        return serverDbVersion.compareTo(currentDbVersion) > 0;
    }

   /**
    * 최신 Profile DB 정보를 서버로부터 가져오는 AsyncTask
    *   
    * DB 버전 및 DB 정보 파일 사이즈를 얻는다.
    * 
    * @author kim.jiseong
    *
    */
	private class DBInfoJob extends AsyncTask<String, Integer, Long> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.setMessage("Checking...");
            mProgressDialog.setCancelable(true);
            mProgressDialog.setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    Toast.makeText(MainActivity.this, "Cancel...", Toast.LENGTH_SHORT);
                }
            });
            
            mProgressDialog.show();
        }

        @Override
        protected Long doInBackground(String... strData) {

            StringBuilder sb = new StringBuilder();
            BufferedReader br = null;

            try {
                URL url = new URL(Constants.DB_INFO_URL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setDoOutput(true);
                httpConn.setUseCaches(false);

                br = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
                
                String temp;
                
                while((temp=br.readLine()) != null) {
                    sb.append(temp);
                }

                JSONObject jsonObj = new JSONObject(sb.toString());
                
                String dbVersion = jsonObj.getString("db_version");
                String dbFileSize = jsonObj.getString("file_size");

                mDbInfo = new DBInfoItem();
                mDbInfo.dbVersion = dbVersion;
                mDbInfo.dbFileSize = Integer.parseInt(dbFileSize);

                Log.v(TAG, "db version : " + dbVersion + ", fileSize : " + dbFileSize);
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());

                return -1L;
            } finally {
                Util.closeSilently(br);
            }

            return 0L;
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            
        }
        
        @Override
        protected void onPostExecute(Long result) {
            mProgressDialog.dismiss();

            if (result == -1L) {
                showDialog(DIALOG_ERROR_DB_INFO);
            } else {
                if (mDbInfo != null && hasUpdated(mDbInfo.dbVersion)) {
                    showDialog(DIALOG_UPDATE);
                } else {
                    showDialog(DIALOG_NOT_UPDATE);
                }
            }
        }
        
        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
	}
	
	/**
	 * 지정된 URL로부터 DB 파일을 다운로드 하여 DB 정보를 갱신하는 AsyncTask class
	 * 
	 * @author kim.jiseong
	 *
	 */
    private class DBDownloadJob extends AsyncTask<String, Integer, Long> {

        private File mTempFile; 
        
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setMessage("Downloading...");
            mProgressDialog.setMax(mDbInfo.dbFileSize);
            mProgressDialog.setCancelable(true);
            mProgressDialog.setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    //
                }
                
            });

            Log.d(TAG, "Profile DB is about to download");
        }

        @Override
        protected Long doInBackground(String... strData) {

            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            
            byte[] buf = new byte[1024];

            try {
                URL url = new URL(Constants.DB_URL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setDoOutput(true);
                httpConn.setUseCaches(false);

                bis = new BufferedInputStream(httpConn.getInputStream(), 4096);

                // SDCARD 임시 파일에 다운로드
                mTempFile = File.createTempFile(getPackageName(), null);
                bos = new BufferedOutputStream(new FileOutputStream(mTempFile));

                int cnt = 0;
                int rcvBytes = 0;

                while((cnt = bis.read(buf)) != -1) {
                    bos.write(buf , 0, cnt);

                    rcvBytes += cnt;
                    publishProgress(rcvBytes);
                }

                bos.flush();

            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
                
                return -1L;
            } finally {
                Util.closeSilently(bis);
                Util.closeSilently(bos);
            }
            
            return 0L;
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            mProgressDialog.setProgress(progress[0]);
        }
        
        @Override
        protected void onPostExecute(Long result) {
            dismissDialog(DIALOG_PROGRESS);
            
            if (result == -1L) {
                showDialog(DIALOG_ERROR_DB_DOWNLOAD);
            } else {
                DatabaseHelper dbHelper = new DatabaseHelper(getBaseContext());
                dbHelper.updateDatabase(mTempFile);
    
                // ShasredPreference에 DB 버전 기록
                SharedPreferences prefs = getSharedPreferences(Constants.DB_VERSION_KEY, Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = prefs.edit();
                editor.putString(Constants.DB_VERSION_KEY, mDbInfo.dbVersion);
                editor.commit();

                Log.d(TAG, "Profile DB has updated to " + mDbInfo.dbVersion);
                
                showDialog(DIALOG_PROGRESS_DONE);
            }
            
            if (mTempFile != null) {
                mTempFile.delete();
            }
        }
        
        @Override
        protected void onCancelled() {
            super.onCancelled();
            
            Log.e(TAG, "onCancelled");
        }
    }

}
